"""
应用程序模块 - 提供Streamlit应用程序入口
"""

import streamlit as st
import pandas as pd
import numpy as np
import logging
from datetime import datetime, timedelta
import traceback

from FDAS.config.settings import (
    APP_TITLE, 
    APP_DESCRIPTION, 
    TIME_RANGE_DAYS,
    ADJUST_METHODS,
    DATA_PERIODS
)
from FDAS.data import get_asset
from FDAS.data.constants import (
    ASSET_TYPE_STOCK,
    ASSET_TYPE_FUTURE,
    ASSET_TYPE_OPTION,
    ASSET_TYPE_FUND,
    ASSET_TYPE_INDEX,
    ASSET_TYPE_ETF
)
from FDAS.agents import (
    StockAnalysisAgent,
    FundAnalysisAgent,
    ETFAnalysisAgent,
    FutureAnalysisAgent,
    OptionAnalysisAgent,
    IndexAnalysisAgent
)
from FDAS.ui.components.sidebar import create_sidebar
from FDAS.ui.utils.formatters import format_dataframe_for_streamlit
from FDAS.visualization.charts.candlestick import create_candlestick_chart
from FDAS.visualization.charts.financial import create_financial_chart
from FDAS.visualization.charts.valuation import create_valuation_chart

logger = logging.getLogger(__name__)

def run_app():
    """运行Streamlit应用程序"""
    # 设置页面配置
    st.set_page_config(
        page_title=APP_TITLE,
        page_icon="📈",
        layout="wide",
        initial_sidebar_state="expanded"
    )
    
    # 应用标题
    st.title(f"🚀 {APP_TITLE}")
    st.markdown(APP_DESCRIPTION)
    
    # 初始化会话状态
    if 'selected_asset' not in st.session_state:
        st.session_state.selected_asset = None
    if 'analysis_result' not in st.session_state:
        st.session_state.analysis_result = None
    if 'asset_data' not in st.session_state:
        st.session_state.asset_data = {}
    
    # 侧边栏 - 资产选择和分析类型
    sidebar_result = create_sidebar()
    
    # 如果用户选择了资产并点击了分析按钮
    if sidebar_result and sidebar_result.get('analyze_clicked', False):
        with st.spinner(f"正在分析 {sidebar_result['asset_name']} ..."):
            try:
                # 获取选择的参数
                symbol = sidebar_result['asset_code']
                asset_type = sidebar_result['asset_type']
                analysis_type = sidebar_result['analysis_type']
                time_range = sidebar_result['time_range']
                adjust_method = sidebar_result.get('adjust_method', 'qfq')
                data_period = sidebar_result.get('data_period', 'daily')
                
                # 获取资产对象
                asset = get_asset(symbol, asset_type)
                
                # 计算日期范围
                end_date = datetime.now().strftime("%Y%m%d")
                start_date = (datetime.now() - timedelta(days=TIME_RANGE_DAYS[time_range])).strftime("%Y%m%d")
                
                # 获取数据
                data = {}
                
                # 根据资产类型获取不同数据
                if asset_type == ASSET_TYPE_STOCK:
                    # 股票数据
                    data['history'] = asset.get_history(
                        start_date=start_date,
                        end_date=end_date,
                        period=data_period,
                        adjust=adjust_method
                    )
                    
                    data['valuation'] = asset.get_valuation()
                    data['financial'] = asset.get_financial()
                    data['news'] = asset.get_news()
                    
                    if analysis_type == '资金流向分析' or analysis_type == '综合分析':
                        data['fund_flow'] = asset.get_fund_flow()
                    
                elif asset_type == ASSET_TYPE_FUND or asset_type == ASSET_TYPE_ETF:
                    # 基金/ETF数据
                    data['history'] = asset.get_history(
                        start_date=start_date,
                        end_date=end_date,
                        period=data_period
                    )
                    
                    data['nav'] = asset.get_nav(
                        start_date=start_date,
                        end_date=end_date
                    )
                    
                    data['portfolio'] = asset.get_portfolio()
                    
                elif asset_type == ASSET_TYPE_FUTURE:
                    # 期货数据
                    data['history'] = asset.get_history(
                        start_date=start_date,
                        end_date=end_date
                    )
                    
                    data['positions'] = asset.get_positions()
                    
                elif asset_type == ASSET_TYPE_OPTION:
                    # 期权数据
                    data['greek_metrics'] = asset.get_greek_metrics()
                    
                elif asset_type == ASSET_TYPE_INDEX:
                    # 指数数据
                    data['history'] = asset.get_history(
                        start_date=start_date,
                        end_date=end_date
                    )
                
                # 保存数据到会话状态
                st.session_state.asset_data = data
                
                # 执行智能分析 - 根据资产类型选择相应的智能体
                if asset_type == ASSET_TYPE_STOCK:
                    agent = StockAnalysisAgent()
                elif asset_type == ASSET_TYPE_FUND:
                    agent = FundAnalysisAgent()
                elif asset_type == ASSET_TYPE_ETF:
                    agent = ETFAnalysisAgent()
                elif asset_type == ASSET_TYPE_FUTURE:
                    agent = FutureAnalysisAgent()
                elif asset_type == ASSET_TYPE_OPTION:
                    agent = OptionAnalysisAgent()
                elif asset_type == ASSET_TYPE_INDEX:
                    agent = IndexAnalysisAgent()
                else:
                    # 默认使用股票智能体
                    agent = StockAnalysisAgent()
                
                query = f"请分析{sidebar_result['asset_name']}({symbol})的{analysis_type}"
                result = agent.analyze(query=query)
                
                # 保存分析结果和选择的资产
                st.session_state.analysis_result = result
                st.session_state.selected_asset = {
                    'code': symbol,
                    'name': sidebar_result['asset_name'],
                    'type': asset_type
                }
                
                st.success("分析完成!")
                
            except Exception as e:
                st.error(f"分析过程中出错: {str(e)}")
                st.error(traceback.format_exc())
                logger.error(f"分析错误: {str(e)}", exc_info=True)
    
    # 主界面 - 分析结果展示
    if st.session_state.selected_asset and st.session_state.analysis_result:
        asset = st.session_state.selected_asset
        asset_type = asset['type']
        data = st.session_state.asset_data
        
        # 创建标签页 - 根据资产类型显示不同标签页
        if asset_type == ASSET_TYPE_STOCK:
            tab1, tab2, tab3, tab4, tab5 = st.tabs([
                "分析报告", "价格走势", "财务指标", "估值分析", "新闻舆情"
            ])
        elif asset_type == ASSET_TYPE_FUND or asset_type == ASSET_TYPE_ETF:
            tab1, tab2, tab3 = st.tabs([
                "分析报告", "净值走势", "持仓分析"
            ])
        elif asset_type == ASSET_TYPE_FUTURE:
            tab1, tab2, tab3 = st.tabs([
                "分析报告", "价格走势", "持仓分析"
            ])
        elif asset_type == ASSET_TYPE_OPTION:
            tab1, tab2 = st.tabs([
                "分析报告", "希腊字母指标"
            ])
        elif asset_type == ASSET_TYPE_INDEX:
            tab1, tab2 = st.tabs([
                "分析报告", "指数走势"
            ])
        else:
            tab1 = st.tabs(["分析报告"])
        
        # 标签页1: 分析报告 (所有资产类型通用)
        with tab1:
            st.header(f"{asset['name']} ({asset['code']}) 分析报告")
            st.markdown(st.session_state.analysis_result)
        
        # 根据资产类型显示不同内容
        if asset_type == ASSET_TYPE_STOCK:
            # 标签页2: 价格走势
            with tab2:
                if 'history' in data and not data['history'].empty:
                    st.subheader("历史价格走势")
                    
                    # 创建K线图
                    df = data['history']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 绘制K线图
                    fig = create_candlestick_chart(df, title=f"{asset['name']} 价格走势")
                    st.plotly_chart(fig, use_container_width=True)
                    
                    # 显示原始数据
                    with st.expander("查看原始数据"):
                        st.dataframe(df)
                else:
                    st.warning("无法获取历史价格数据")
            
            # 标签页3: 财务指标
            with tab3:
                if 'financial' in data and data['financial']:
                    st.subheader("财务指标分析")
                    
                    # 获取财务数据
                    fin_data = data['financial']
                    
                    # 创建财务指标可视化
                    if 'income_statement' in fin_data and not fin_data['income_statement'].empty:
                        # 处理财务数据
                        income_df = fin_data['income_statement']
                        income_df = format_dataframe_for_streamlit(income_df)
                        
                        # 收入和利润趋势
                        if '营业收入' in income_df.columns and '净利润' in income_df.columns:
                            fig = create_financial_chart(
                                income_df, 
                                x_col='报告期', 
                                y_cols=['营业收入', '净利润'],
                                title="收入与利润趋势"
                            )
                            st.plotly_chart(fig, use_container_width=True)
                        
                        # 显示原始财务数据
                        with st.expander("查看财务报表数据"):
                            st.dataframe(income_df)
                    else:
                        st.warning("无法获取财务数据")
            
            # 标签页4: 估值分析
            with tab4:
                if 'valuation' in data and not data['valuation'].empty:
                    st.subheader("估值指标分析")
                    
                    # 获取估值数据
                    val_df = data['valuation']
                    val_df = format_dataframe_for_streamlit(val_df)
                    
                    # 创建估值指标可视化
                    if 'PE(TTM)' in val_df.columns and '市净率' in val_df.columns:
                        # PE和PB趋势
                        fig = create_valuation_chart(val_df, title="PE和PB趋势")
                        st.plotly_chart(fig, use_container_width=True)
                    
                    # 显示原始估值数据
                    with st.expander("查看估值数据"):
                        st.dataframe(val_df)
                else:
                    st.warning("无法获取估值数据")
            
            # 标签页5: 新闻舆情
            with tab5:
                if 'news' in data and len(data['news']) > 0:
                    st.subheader("相关新闻")
                    
                    news_data = data['news']
                    
                    for i, news in enumerate(news_data):
                        with st.container():
                            st.markdown(f"### {news.get('新闻标题', '无标题')}")
                            st.markdown(f"**发布时间**: {news.get('发布时间', '未知')} | **来源**: {news.get('文章来源', '未知')}")
                            st.markdown(f"{news.get('新闻内容', '')[:200]}...")
                            if '新闻链接' in news:
                                st.markdown(f"[阅读全文]({news['新闻链接']})")
                            st.divider()
                else:
                    st.warning("无法获取新闻数据")
        
        # 基金类型的标签页内容
        elif asset_type == ASSET_TYPE_FUND:
            # 标签页2: 净值走势
            with tab2:
                if 'nav' in data and not data['nav'].empty:
                    st.subheader("净值走势")
                    
                    # 显示净值数据
                    df = data['nav']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 绘制净值走势图
                    fig = create_financial_chart(
                        df,
                        x_col='日期',
                        y_cols=['单位净值', '累计净值'],
                        title=f"{asset['name']} 净值走势"
                    )
                    st.plotly_chart(fig, use_container_width=True)
                    
                    # 显示原始数据
                    with st.expander("查看原始数据"):
                        st.dataframe(df)
                else:
                    st.warning("无法获取净值数据")
            
            # 标签页3: 持仓分析
            with tab3:
                if 'portfolio' in data and data['portfolio']:
                    st.subheader("持仓分析")
                    
                    # 显示持仓数据
                    portfolio = data['portfolio']
                    
                    # 行业分布
                    if 'industry' in portfolio and portfolio['industry']:
                        st.subheader("行业分布")
                        industry_df = pd.DataFrame(portfolio['industry'])
                        st.dataframe(industry_df)
                    
                    # 重仓股
                    if 'stocks' in portfolio and portfolio['stocks']:
                        st.subheader("重仓股票")
                        stocks_df = pd.DataFrame(portfolio['stocks'])
                        st.dataframe(stocks_df)
                    
                    # 资产配置
                    if 'asset_allocation' in portfolio and portfolio['asset_allocation']:
                        st.subheader("资产配置")
                        allocation_df = pd.DataFrame(portfolio['asset_allocation'])
                        st.dataframe(allocation_df)
                else:
                    st.warning("无法获取持仓数据")
        
        # ETF类型的标签页内容
        elif asset_type == ASSET_TYPE_ETF:
            # 标签页2: 净值走势
            with tab2:
                if 'nav' in data and not data['nav'].empty:
                    st.subheader("净值走势")
                    
                    # 显示净值数据
                    df = data['nav']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 绘制净值走势图
                    fig = create_financial_chart(
                        df,
                        x_col='日期',
                        y_cols=['单位净值', '累计净值'],
                        title=f"{asset['name']} 净值走势"
                    )
                    st.plotly_chart(fig, use_container_width=True)
                    
                    # 折溢价信息（ETF特有）
                    if 'premium_discount' in data and data['premium_discount']:
                        st.subheader("折溢价信息")
                        st.metric(
                            "当前溢价率",
                            f"{data['premium_discount'].get('premium_discount', 0.0):.2f}%",
                            help="溢价率 = (ETF价格 - 单位净值) / 单位净值 × 100%"
                        )
                        
                        col1, col2 = st.columns(2)
                        with col1:
                            st.metric("近1月平均溢价率", f"{data['premium_discount'].get('average_premium', 0.0):.2f}%")
                        with col2:
                            st.metric("近1月最大溢价率", f"{data['premium_discount'].get('max_premium', 0.0):.2f}%")
                    
                    # 显示原始数据
                    with st.expander("查看原始数据"):
                        st.dataframe(df)
                else:
                    st.warning("无法获取净值数据")
            
            # 标签页3: 持仓分析
            with tab3:
                if 'portfolio' in data and data['portfolio']:
                    st.subheader("持仓分析")
                    
                    # 跟踪误差（ETF特有）
                    if 'tracking_error' in data:
                        st.metric(
                            "跟踪误差",
                            f"{data.get('tracking_error', 0.0):.4f}",
                            help="衡量ETF与跟踪指数偏离程度的指标"
                        )
                    
                    # 显示持仓数据
                    portfolio = data['portfolio']
                    
                    # 行业分布
                    if 'industry' in portfolio and portfolio['industry']:
                        st.subheader("行业分布")
                        industry_df = pd.DataFrame(portfolio['industry'])
                        st.dataframe(industry_df)
                    
                    # 重仓股
                    if 'stocks' in portfolio and portfolio['stocks']:
                        st.subheader("重仓股票")
                        stocks_df = pd.DataFrame(portfolio['stocks'])
                        st.dataframe(stocks_df)
                else:
                    st.warning("无法获取持仓数据")
        
        # 期货类型的标签页内容
        elif asset_type == ASSET_TYPE_FUTURE:
            # 标签页2: 价格走势
            with tab2:
                if 'history' in data and not data['history'].empty:
                    st.subheader("价格走势")
                    
                    # 创建K线图
                    df = data['history']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 绘制K线图
                    fig = create_candlestick_chart(df, title=f"{asset['name']} 价格走势")
                    st.plotly_chart(fig, use_container_width=True)
                    
                    # 显示原始数据
                    with st.expander("查看原始数据"):
                        st.dataframe(df)
                else:
                    st.warning("无法获取历史价格数据")
            
            # 标签页3: 持仓分析
            with tab3:
                if 'positions' in data and not data['positions'].empty:
                    st.subheader("持仓分析")
                    
                    # 显示持仓数据
                    df = data['positions']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 多空持仓对比
                    st.subheader("多空持仓分布")
                    if '多头持仓' in df.columns and '空头持仓' in df.columns:
                        col1, col2 = st.columns(2)
                        with col1:
                            st.metric("多头持仓", f"{df['多头持仓'].iloc[0]:,}")
                        with col2:
                            st.metric("空头持仓", f"{df['空头持仓'].iloc[0]:,}")
                    
                    # 显示原始数据
                    st.dataframe(df)
                    
                    # 期货特有信息
                    if 'basis' in data and not data['basis'].empty:
                        st.subheader("基差分析")
                        basis_df = data['basis']
                        basis_df = format_dataframe_for_streamlit(basis_df)
                        st.dataframe(basis_df)
                        
                    if 'term_structure' in data and not data['term_structure'].empty:
                        st.subheader("期限结构")
                        term_df = data['term_structure']
                        term_df = format_dataframe_for_streamlit(term_df)
                        st.dataframe(term_df)
                else:
                    st.warning("无法获取持仓数据")
        
        # 期权类型的标签页内容
        elif asset_type == ASSET_TYPE_OPTION:
            # 标签页2: 希腊字母指标
            with tab2:
                if 'greek_metrics' in data and data['greek_metrics']:
                    st.subheader("希腊字母指标")
                    
                    greeks = data['greek_metrics']
                    
                    # 展示希腊字母指标
                    col1, col2, col3 = st.columns(3)
                    with col1:
                        st.metric("Delta", f"{greeks.get('delta', 0.0):.4f}")
                        st.metric("Gamma", f"{greeks.get('gamma', 0.0):.4f}")
                    with col2:
                        st.metric("Theta", f"{greeks.get('theta', 0.0):.4f}")
                        st.metric("Vega", f"{greeks.get('vega', 0.0):.4f}")
                    with col3:
                        st.metric("Rho", f"{greeks.get('rho', 0.0):.4f}")
                        st.metric("隐含波动率", f"{data.get('implied_volatility', 0.0):.2f}%")
                    
                    # 期权价值组成
                    if 'intrinsic_value' in data and 'time_value' in data:
                        st.subheader("期权价值组成")
                        col1, col2 = st.columns(2)
                        with col1:
                            st.metric("内在价值", f"{data.get('intrinsic_value', 0.0):.2f}")
                        with col2:
                            st.metric("时间价值", f"{data.get('time_value', 0.0):.2f}")
                    
                    # 标的资产信息
                    if 'underlying_info' in data and data['underlying_info']:
                        st.subheader("标的资产信息")
                        st.json(data['underlying_info'])
                else:
                    st.warning("无法获取希腊字母指标数据")
        
        # 指数类型的标签页内容
        elif asset_type == ASSET_TYPE_INDEX:
            # 标签页2: 指数走势
            with tab2:
                if 'history' in data and not data['history'].empty:
                    st.subheader("指数走势")
                    
                    # 创建K线图
                    df = data['history']
                    df = format_dataframe_for_streamlit(df)
                    
                    # 绘制K线图
                    fig = create_candlestick_chart(df, title=f"{asset['name']} 指数走势")
                    st.plotly_chart(fig, use_container_width=True)
                    
                    # 显示原始数据
                    with st.expander("查看原始数据"):
                        st.dataframe(df)
                    
                    # 指数成分和权重
                    if 'components' in data and not data['components'].empty:
                        with st.expander("查看指数成分股"):
                            comp_df = data['components']
                            comp_df = format_dataframe_for_streamlit(comp_df)
                            st.dataframe(comp_df)
                    
                    if 'weight' in data and not data['weight'].empty:
                        with st.expander("查看成分股权重"):
                            weight_df = data['weight']
                            weight_df = format_dataframe_for_streamlit(weight_df)
                            st.dataframe(weight_df)
                    
                    if 'industry_distribution' in data and data['industry_distribution']:
                        st.subheader("行业分布")
                        st.json(data['industry_distribution'])
                else:
                    st.warning("无法获取指数历史数据")
    
    # 如果没有选择资产，显示首页内容
    else:
        st.info("👈 请在侧边栏选择资产并执行分析")
        
        # 显示平台介绍
        st.header("平台功能")
        
        col1, col2, col3 = st.columns(3)
        
        with col1:
            st.markdown("### 📊 多资产分析")
            st.markdown("""
            - 股票分析
            - 期货分析
            - 期权分析
            - 基金分析
            - 指数分析
            - ETF分析
            """)
        
        with col2:
            st.markdown("### 🤖 AI驱动")
            st.markdown("""
            - 基于LangGraph智能工作流
            - OpenAI大模型支持
            - 自然语言交互
            - 智能报告生成
            """)
        
        with col3:
            st.markdown("### 📈 数据可视化")
            st.markdown("""
            - K线图表
            - 财务指标趋势
            - 估值指标对比
            - 资金流向分析
            - 新闻舆情监控
            """)
        
        # 使用说明
        st.header("使用说明")
        st.markdown("""
        1. 在侧边栏选择资产类型
        2. 输入资产代码或名称
        3. 从搜索结果中选择目标资产
        4. 选择分析类型和时间范围
        5. 点击"执行分析"按钮
        6. 在标签页中查看分析结果和可视化图表
        """)
    
    # 页脚
    st.markdown("---")
    st.markdown(f"© {datetime.now().year} {APP_TITLE} | 基于LangGraph, LangChain, AKShare和Streamlit构建")